﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Data;
using System.Reflection;
using System.Security.Cryptography;
using System.Web.Security;
using System.Text.RegularExpressions;
using System.IO;
using System.Collections;
using System.Web.SessionState;
using MySql.Data.MySqlClient;
using System.Security;
using XQ.Framework.html;
using XQ.Framework.core;
using XQ.Framework.cache;

namespace XQ.Framework.common
{
    /// <summary>
    /// 公共方法类
    /// </summary>
    public class Com
    {
        public static string getUUID()
        {
            return Guid.NewGuid().ToString();
        }
        public static bool ReferenceEquals(object obj1, object obj2)
        {
            return object.ReferenceEquals(obj1, obj2);
        }
        /// <summary>
        /// 取字符串拼音首字母
        /// </summary>
        /// <param name="value">原字符串</param>
        /// <param name="length">所要取拼音首字母的字符数</param>
        public static string GetSpell(string value)
        {
            //27个
            int[] beginArr = new int[] { 
            45217, 45253, 45761, 46318, 46826, 47010, 47297, 47614,48119, 48119, 49062,
            49324, 49896, 50371, 50614, 50622, 50906, 51387, 51446, 52218, 52698, 52698, 
            52698, 52980, 53689, 54481, 55295 };
            //26个
            char[] characters = new char[] { 
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k','l', 'm', 'n', 'o', 'p', 
            'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
            string spell = string.Empty;
            byte[] b = null;
            value.ToList().ForEach(delegate(char c)
            {
                if ((b = Encoding.Default.GetBytes(c.ToString())) == null)
                {
                    spell += " ";
                    return;
                }
                if (b.Length == 1)
                {
                    spell += c;
                    return;
                }
                //b.Length!=1
                int code = (short)b[0] * 256 + (short)b[1];
                for (int i = 0; i < characters.Length; ++i)
                {
                    if (code >= beginArr[i] && code < beginArr[i + 1])
                    {
                        spell += characters[i];
                        return;//如果找到了就返回这个委托方法[如果是for循环要设置标志]
                    }
                }
                spell += " ";
            });
            return spell;
        }
        public static void ResponseWrite(string html)
        {
            if (HttpContext.Current != null)
            {
                HttpContext.Current.Response.Write(html);
            }
        }
        /// <summary>
        /// 获取交集
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static List<T> GetInterSection<T>(IList<T> a, IList<T> b)
        {
            if (!ValidateHelper.IsPlumpList(a) || !ValidateHelper.IsPlumpList(b)) { return null; }
            return a.Where(x => b.Contains(x)).ToList();
        }
        public static List<T> UpdateList<T>(List<T> list, T newItem, int maxCount)
        {
            if (list.Count >= maxCount)
            {
                for (int i = 0; i < list.Count - 1; ++i)
                {
                    list[i] = list[i + 1];
                }
                list.RemoveAt(list.Count - 1);
            }
            list.Add(newItem);
            return list;
        }
        public static List<T> UpdateList<T>(ref List<T> list, T newItem, int maxCount)
        {
            if (list.Count >= maxCount)
            {
                for (int i = 0; i < list.Count - 1; ++i)
                {
                    list[i] = list[i + 1];
                }
                list.RemoveAt(list.Count - 1);
            }
            list.Add(newItem);
            return list;
        }
        /// <summary>
        /// 多个集合里取交集
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="lists"></param>
        /// <returns></returns>
        public static List<T> GetInterSectionFromAny<T>(params IList<T>[] lists)
        {
            if (!ValidateHelper.IsPlumpArray(lists) || lists.Length < 2) { return null; }
            List<T> interSection = GetInterSection(lists[0], lists[1]);
            for (int i = 3; i < lists.Length; ++i)
            {
                //发现有非交集的就中断
                if (!ValidateHelper.IsPlumpList(interSection = GetInterSection(interSection, lists[i])))
                {
                    break;
                }
            }
            return interSection;
        }
        /// <summary>
        /// 如果使用缓存：如果缓存中有，就直接取。如果没有就先获取并加入缓存
        /// 如果不使用缓存：直接从数据源取。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="context"></param>
        /// <param name="key"></param>
        /// <param name="dataSource"></param>
        /// <param name="use_cache"></param>
        /// <returns></returns>
        public static T CacheLogic<T>(HttpContext context, string key, Func<T> dataSource, bool use_cache = true)
        {
            try
            {
                //如果读缓存，读到就返回
                if (use_cache)
                {
                    object cache = CacheManager.GetCacheObject(context, key);
                    if (ValidateHelper.Is<T>(cache))
                    {
                        //ResponseWrite("<!--cache-->");
                        return (T)cache;
                    }
                }
                //没有读到缓存，从数据源生成
                if (dataSource != null)
                {
                    object data = dataSource.Invoke();
                    if (ValidateHelper.Is<T>(data))
                    {
                        T obj = (T)data;
                        if (use_cache)
                        {
                            CacheManager.AddCache(context, key, obj);
                        }
                        //ResponseWrite("<!--no cache-->");
                        return obj;
                    }
                }
                return default(T);
            }
            catch (Exception e)
            {
                return default(T);
            }
        }
        /// <summary>
        /// 获取参数中第一个有效的字符串
        /// </summary>
        /// <param name="strs"></param>
        /// <returns></returns>
        public static string GetFirstPlumpString(params string[] strs)
        {
            if (strs != null && strs.Count() > 0)
            {
                for (int i = 0; i < strs.Count(); ++i)
                {
                    if (ValidateHelper.IsPlumpString(strs[i]))
                    {
                        return strs[i];
                    }
                }
            }
            return string.Empty;
        }
        public static void Swap(ref int a, ref int b)
        {
            //bool eq = a << 32 == Math.Pow(2, 32) * a;
            a = a ^ b;
            b = a ^ b;
            a = a ^ b;
        }
        public static void Swap<T>(ref T a, ref T b)
        {
            T temp;
            temp = b;
            b = a;
            a = temp;
        }
        /// <summary>
        /// 格式化数字，比如（100000-100,000）
        /// </summary>
        /// <param name="num">需要格式化的数字</param>
        /// <returns></returns>
        public static string FormatNum(string num)
        {
            if (!RegexHelper.IsMatch(num, RegexHelper.INT))
            {
                return string.Empty;
            }
            string re = string.Empty;
            char[] chars = num.ToArray();
            int j = 0;
            for (int i = chars.Length - 1; i >= 0; i--)
            {
                j++;
                if (j == 3 && i != 0)
                {
                    re = "," + chars[i] + re;
                    j = 0;
                }
                else
                {
                    re = chars[i] + re;
                }
            }
            return re;
        }
        /// <summary>
        /// 取出字符串的所有" "
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string removeAllSpace(string str)
        {
            StringBuilder re = new StringBuilder();
            List<char> list = str.ToList<char>();
            list.ForEach(delegate(char c)
            {
                re.Append(c == ' ' ? string.Empty : c.ToString());
            });
            return re.ToString();
        }
        /// <summary>
        /// 获取字符前几位，并加省略号
        /// </summary>
        /// <param name="str"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public static string getPreviewString(string str, int len)
        {
            str = ConvertHelper.getString(str);
            return (str.Length <= len) ? str : str.Substring(0, len) + "...";
        }
        public static bool isListContain(List<string> list, string item)
        {
            if (list == null) { return false; }
            for (int i = 0; i < list.Count; ++i)
            {
                if (list[i] == item) { return true; }
            }
            return false;
        }
        public static string getRandomNumString(int len = 10)
        {
            StringBuilder str = new StringBuilder();
            Random ran = new Random();
            while (true)
            {
                if ((--len) < 0) { break; }
                str.Append(ran.Next(9));
            }
            return str.ToString();
        }
        public static V getData<K, V>(Dictionary<K, V> data, K key)
        {
            try
            {
                if (data == null || !data.Keys.Contains(key)) { return default(V); }
                return data[key];
            }
            catch
            {
                return default(V);
            }
        }
        /// <summary>
        /// 冒泡排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <param name="bigToSmall"></param>
        /// <returns></returns>
        public static T[] Sort<T>(T[] data, Func<T, T, bool> changePos)
        {
            if (!ValidateHelper.IsPlumpArray(data) || changePos == null) { return data; }
            for (int i = 0; i < data.Length - 1; ++i)
            {
                for (int j = 0; j < data.Length - i - 1; ++j)
                {
                    if (changePos.Invoke(data[j], data[j + 1]))
                    {
                        Com.Swap<T>(ref data[j], ref data[j + 1]);
                        /* Swap data
                        T temp = data[j];
                        data[j] = data[j + 1];
                        data[j + 1] = temp;*/
                    }
                }
            }
            return data;
        }
        public static List<T> SortList<T>(List<T> data, Func<T, T, bool> changePos)
        {
            if (!ValidateHelper.IsPlumpList(data) || changePos == null) { return data; }
            return Sort(data.ToArray(), changePos).ToList();
        }

        public static string HtmlEncode(string text)
        {
            return text.Replace("&", "&amp;").Replace("\"", "&quot;").Replace("<", "&lt;").Replace(">", "&gt;");
        }

        public static string HtmlDecode(string text)
        {
            return text.Replace("&quot;", "\"").Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&");
        }
        /// <summary>
        /// 转换性别 1：男 0：女 else：未知
        /// </summary>
        /// <param name="sex"></param>
        /// <returns></returns>
        public static string getSex(string sex)
        {
            return (sex == "1") ? "男" : "女";
        }
        public static string DictToString(Dictionary<string, object> data)
        {
            if (data == null || data.Count == 0) { return string.Empty; }
            string val = string.Empty;
            data.Keys.ToList().ForEach(delegate(string key)
            {
                val += (val == string.Empty ? "" : "&") + key + "=" + ConvertHelper.getString(data[key]);
            });
            return val;
        }
        public List<T> removeItemFromListInSafe<T>(ref List<T> list, T item) where T : IComparable<T>
        {
            try
            {
                if (list != null && list.Count > 0)
                {
                    for (int i = list.Count - 1; i >= 0; --i)
                    {
                        if (list[i] == null || list[i].CompareTo(item) != 0) { continue; }
                        list.RemoveAt(i);
                    }
                }
                return list;
            }
            catch (Exception e)
            {
                return null;
            }
        }
        /// <summary>
        /// 获取错误信息，隐藏于html中
        /// </summary>
        /// <param name="err"></param>
        /// <returns></returns>
        public static string getHiddenError(string err)
        {
            return "<span style='font-size:30px;'>【SERVER ERROR =。=】</span><span style='display:none;'>" + err + "</span>";
        }
        public static string getHtmlNotes(string note)
        {
            return string.Format("<!--{0}-->", ConvertHelper.getString(note));
        }
        public static string getYellowBlockHtml(string html)
        {
            return "<div class='yellow_block'>" + html + "</div>";
        }
        public static int getPageCount(int item_count, int page_size)
        {
            if (page_size == 0) { return 100000; }
            return item_count % page_size == 0 ? (item_count / page_size) : (item_count / page_size + 1);
        }
        public static string[] getMysqlLimit(int current_page, int page_size)
        {
            current_page = current_page < 1 ? 1 : current_page;
            return new string[] { ConvertHelper.getString((current_page - 1) * page_size), ConvertHelper.getString(page_size) };
        }


        /// <summary>
        ///获得邮箱提供者
        /// </summary>
        /// <param name="email">邮箱</param>
        /// <returns></returns>
        public static string GetEmailProvider(string email)
        {
            int index = email.LastIndexOf('@');
            if (index > 0)
                return email.Substring(index + 1);
            return string.Empty;
        }

        /// <summary>
        /// 转义正则表达式
        /// </summary>
        public static string EscapeRegex(string s)
        {
            string[] oList = { "\\", ".", "+", "*", "?", "{", "}", "[", "^", "]", "$", "(", ")", "=", "!", "<", ">", "|", ":" };
            string[] eList = { "\\\\", "\\.", "\\+", "\\*", "\\?", "\\{", "\\}", "\\[", "\\^", "\\]", "\\$", "\\(", "\\)", "\\=", "\\!", "\\<", "\\>", "\\|", "\\:" };
            for (int i = 0; i < oList.Length; i++)
                s = s.Replace(oList[i], eList[i]);
            return s;
        }

        /// <summary>
        /// 将ip地址转换成Int64类型
        /// </summary>
        /// <param name="ip">ip</param>
        /// <returns></returns>
        public static Int64 ConvertIPToInt64(string ip)
        {
            return Convert.ToInt64(ip.Replace(".", string.Empty));
        }
        public static string GetPlumpString(string str, string deft)
        {
            return ValidateHelper.IsPlumpString(str) ? str : deft;
        }
        /// <summary>
        /// 隐藏邮箱
        /// </summary>
        public static string HideEmail(string email)
        {
            int index = email.LastIndexOf('@');

            if (index == 1)
                return "*" + email.Substring(index);
            if (index == 2)
                return email[0] + "*" + email.Substring(index);

            StringBuilder sb = new StringBuilder();
            sb.Append(email.Substring(0, 2));
            int count = index - 2;
            while (count > 0)
            {
                sb.Append("*");
                count--;
            }
            sb.Append(email.Substring(index));
            return sb.ToString();
        }

        /// <summary>
        /// 隐藏手机
        /// </summary>
        public static string HideMobile(string mobile)
        {
            return mobile.Substring(0, 3) + "*****" + mobile.Substring(8);
        }

        /// <summary>
        /// 数据转换为列表
        /// </summary>
        /// <param name="array">数组</param>
        /// <returns></returns>
        public static List<T> ArrayToList<T>(T[] array)
        {
            List<T> list = new List<T>(array.Length);
            foreach (T item in array)
                list.Add(item);
            return list;
        }

        public static List<T> ReversalList<T>(List<T> list)
        {
            if (list == null || list.Count() < 2) { return list; }
            T temp;
            for (int i = 0; i < list.Count() / 2; ++i)
            {
                temp = list[i];
                list[i] = list[list.Count() - 1 - i];
                list[list.Count() - 1 - i] = temp;
            }
            return list;
        }
        public static int getMin(params int[] nums)
        {
            int min = 0;
            for (int i = 0; i < nums.Length; ++i)
            {
                if (min > nums[i])
                {
                    min = nums[i];
                }
            }
            return min;
        }
        public static int getMax(params int[] nums)
        {
            int max = 0;
            for (int i = 0; i < nums.Length; ++i)
            {
                if (max < nums[i])
                {
                    max = nums[i];
                }
            }
            return max;
        }
        /// <summary>
        /// 通过空格 中英文逗号分隔
        /// </summary>
        /// <param name="tags"></param>
        /// <returns></returns>
        public static List<string> SplitTags(string tags)
        {
            List<string> list = StringHelper.Split(tags, ' ', ',', '，');
            if (!ValidateHelper.IsPlumpList(list))
            {
                return list;
            }
            return list.Where(x => ValidateHelper.IsInRange(x, 1, 6)).ToList();
        }
        /// <summary>
        /// 过滤没用的tag
        /// </summary>
        /// <param name="tags"></param>
        /// <returns></returns>
        public string FormatTagsString(string tags)
        {
            return StringHelper.Join(",", SplitTags(tags));
        }

        public static List<string> SplitStringToList(string str, string spliter)
        {
            List<string> list = new List<string>();
            string[] arr = ConvertHelper.getString(str).Split(new string[] { spliter }, StringSplitOptions.None);
            if (arr != null && arr.Length > 0)
            {
                for (int i = 0; i < arr.Length; ++i)
                {
                    list.Add(arr[i]);
                }
            }
            return list;
        }

        public static Dictionary<TKey, List<TSource>> LinqGroupBy<TSource, TKey>(IList<TSource> list, Func<TSource, TKey> groupSelector)
        {
            Dictionary<TKey, List<TSource>> dict = new Dictionary<TKey, List<TSource>>();
            if (!ValidateHelper.IsPlumpList(list))
            {
                return dict;
            }
            List<IGrouping<TKey, TSource>> groups = list.GroupBy(groupSelector).ToList();
            groups.ForEach(delegate(IGrouping<TKey, TSource> group)
            {
                dict.Add(group.Key, group.ToList());
            });
            return dict;
        }

        /// <summary>
        /// 转全角的函数(SBC case)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string ToSBC(string input)
        {
            //半角转全角：
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 32)
                {
                    c[i] = (char)12288;
                    continue;
                }
                if (c[i] < 127)
                {
                    c[i] = (char)(c[i] + 65248);
                }
            }
            return new string(c);
        }

        /// <summary>
        ///  转半角的函数(SBC case)
        /// </summary>
        /// <param name="input">输入</param>
        /// <returns></returns>
        public static string ToDBC(string input)
        {
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 12288)
                {
                    c[i] = (char)32;
                    continue;
                }
                if (c[i] > 65280 && c[i] < 65375)
                {
                    c[i] = (char)(c[i] - 65248);
                }
            }
            return new string(c);
        }

        #region 非递归历遍树算法
        /*
        public void pre_order_traverse(TreeNode root)
        {
            Stack stack = new Stack(200);
            stack.Push(root);
            TreeNode cur_node = null;
            while (stack.Count != 0)
            {
                //this is current node
                cur_node = (TreeNode)stack.Pop();
                MessageBox.Show(string.Format("count:{0},text:{1}", stack.Count, cur_node.Text));
                //next node of current node
                if (cur_node.NextNode != null)
                {
                    stack.Push(cur_node.NextNode);
                }
                //first child of current node
                if (cur_node.Nodes.Count > 0)
                {
                    stack.Push(cur_node.Nodes[0]);
                }
            }
        }*/
        /*
         public void BuildTree(TreeNode node)
        {
            //use node object
            node.Name = "new name";
            //load chils of node
            TreeNodeCollection childs = node.Nodes;
            if (childs == null || childs.Count == 0) { return; }
            for (int i = 0; i < childs.Count; ++i)
            {
                BuildTree(childs[i]);
            }
        }
         */
        #endregion

    }
}